package t1021

import (
	"errors"
	"strings"
	"sync"
)

type MyStack struct {
	items []string
	l     sync.Mutex
}

func (m *MyStack) Push(n string) {
	m.l.Lock()
	defer m.l.Unlock()
	m.items = append(m.items, n)
}

func (m *MyStack) Pop() (string, error) {
	m.l.Lock()
	defer m.l.Unlock()
	if len(m.items) == 0 {
		return "", errors.New("empty of stack")
	}
	el := m.items[len(m.items)-1]
	m.items = m.items[:len(m.items)-1]
	return el, nil
}

func (m *MyStack) Top() (string, error) {
	m.l.Lock()
	defer m.l.Unlock()
	if len(m.items) == 0 {
		return "", errors.New("empty of stack")
	}
	el := m.items[len(m.items)-1]
	return el, nil
}

func (m *MyStack) Size() int {
	return len(m.items)
}

func (m *MyStack) Empty() bool {
	if len(m.items) == 0 {
		return true
	}
	return false
}

func (m *MyStack) String() string {
	return strings.Join(m.items, "")
}
